package com.guanyu.u2cache.caffeine;

import cn.hutool.core.util.ObjectUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.guanyu.u2cache.util.KeyUtil;
import com.guanyu.u2cache.util.TimeUtil;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhouyunjian
 * @date 2023/12/04 09:53
 **/
public class U2CacheManager {
    /**
     * 最外层缓存：包装内部Cache缓存结果
     * default便于内部包访问
     * final不允许
     */
    Map<String, Cache<String, Object>> cacheMap = new ConcurrentHashMap(16);
    /**
     * 热点统计：
     * 第一层key-name+key 名称
     * 第二层key-热点时间，记录到分钟级别/小时级别 todo 默认先到分钟级别
     */
    Map<String, Map<String, Long>> hotSpotCountMap = new ConcurrentHashMap<>(100);
    /**
     * final不允许，否则影响计算存储空间
     */
    public static U2CacheManager singleton = new U2CacheManager();

    public static U2CacheManager getSingleton() {
        return singleton;
    }

    @Nullable
    public Cache<String, Object> getCache(String name) {
        return cacheMap.get(name);
    }

    @Nullable
    public Object getCacheByKey(String name, String key, boolean openHotLog) {
        Cache<String, Object> cache = getCache(name);
        if (ObjectUtil.isEmpty(cache)) {
            return null;
        }
        openHotLog(name, key, openHotLog);
        return cache.getIfPresent(key);
    }

    /**
     * 打开热点key统计数据
     *
     * @param openHotLog
     */
    private void openHotLog(String name, String key, boolean openHotLog) {
        if (!openHotLog) {
            return;
        }
        String hotKey = KeyUtil.createKey(name, key);
        Map<String, Long> timeMap = hotSpotCountMap.getOrDefault(hotKey, new HashMap(16));
        String currentTime = TimeUtil.getCurrentTime();
        Long count = timeMap.getOrDefault(currentTime, 0L);
        timeMap.put(currentTime, ++count);
        hotSpotCountMap.putIfAbsent(hotKey, timeMap);
    }

    /**
     * 注册系统缓存
     *
     * @param name
     */
    public void registerCustomCache(String name) {
        Cache<String, Object> build = Caffeine.newBuilder()
                .initialCapacity(1000)
                //.maximumSize(100000)
                .removalListener(new CaffeineRemovalListener())
                .expireAfter(new CaffeineExpiry()).build();
        cacheMap.put(name, build);
    }

    public boolean isExist(String name) {
        return cacheMap.containsKey(name);
    }

    /**
     * 删除系统缓存
     *
     * @param name
     */
    public void destroyCustomCache(String name) {
        cacheMap.get(name);
    }


}
